home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Classes / browser / BrowserMatrix.m < prev   
Text File  |  1995-06-12  |  5KB  |  248 lines

  1. #import "BrowserMatrix.h"
  2. #import <objc/List.h>
  3. #import <appkit/SelectionCell.h>
  4. #import <sys/types.h>
  5. #import <sys/stat.h>
  6. #import <sys/file.h>
  7. #import <math.h>
  8.  
  9. static int slaveRow;
  10.  
  11. extern int strcmp(), strlen(), stat();
  12. extern char *strcat(), *rindex();
  13.  
  14. @implementation BrowserMatrix
  15.  
  16. + newFrame:(NXRect *)r
  17. {
  18.     NXSize r1;
  19.     float height;
  20.     
  21.     self = [super newFrame:r
  22.               mode:NX_RADIOMODE
  23.               cellClass:[SelectionCell class]
  24.               numRows:0
  25.               numCols:1];
  26.     slaves = [List new];
  27.     master = nil;
  28.     alphabetize = YES;
  29.     height = r->size.height;
  30.     visEntries = (int) floor ((double)height / TEXTHEIGHT);
  31.     cellSize.height = height / (float) visEntries;
  32.     cellSize.width = r->size.width;
  33.     intercell.width = intercell.height = 0.0;
  34.     mFlags.allowEmptySel = YES;
  35.     topRow = 0;
  36.     return self;
  37. }
  38.  
  39. - mouseDown:(NXEvent *)event
  40. {
  41.     int i, count;
  42.  
  43.     if (master != nil) return self;
  44.     if ((count = [slaves count]) == 0) {
  45.         [super mouseDown:event];
  46.         return self;
  47.         }
  48.     [window disableFlushWindow];
  49.     [super mouseDown:event];
  50.     for (i = 0; i < count; i++) {
  51.         [[slaves objectAt:i] selectEntryAt:selectedRow];
  52.         }
  53.     [window reenableFlushWindow];
  54.     [window flushWindow];
  55.     return self;
  56. }
  57.  
  58. - selectEntryAt:(int)row
  59. {
  60.     if (row < numRows) {
  61.         if (master == nil) [window disableFlushWindow];
  62.         [self selectCellAt:row :0];
  63.         [self sendAction];
  64.         [slaves makeObjectsPerform:@selector(selectEntryAt:)
  65.             with:(id)row];
  66.         if (master == nil) {
  67.             [window reenableFlushWindow];
  68.             [window flushWindow];
  69.             }
  70.         }
  71.     return self;
  72. }
  73.  
  74. - clear
  75. {
  76.     int row, count;
  77.     
  78.     count = numRows;
  79.     for (row = 0; row < count; row++) [self removeRowAt:0 andFree:YES];
  80.     topRow = 0;
  81.     [slaves makeObjectsPerform:@selector(clear)];
  82.     return self;
  83. }
  84.  
  85. - display
  86. {
  87.     [self sizeToCells];
  88.     if ([slaves count] == 0) {
  89.         [super display];
  90.         return self;
  91.         }
  92.     [window disableFlushWindow];
  93.     [super display];
  94.     [slaves makeObjectsPerform:@selector(display)];
  95.     [window reenableFlushWindow];
  96.     [window flushWindow];
  97.     return self;
  98. }
  99.  
  100. - (BOOL)atTop
  101. {
  102.     return topRow == 0;
  103. }
  104.  
  105. - (BOOL)atBottom
  106. {
  107.     return (topRow + visEntries) >= numRows;
  108. }
  109.  
  110. - scrollDown:sender
  111. {
  112.     int bottomRow;
  113.     
  114.     if ((master != nil) && ([sender class] != [BrowserMatrix class]))
  115.         return self;
  116.     if ((bottomRow = ++topRow + visEntries - 1) >= numRows) {
  117.         --topRow;
  118.         --bottomRow;
  119.         return self;
  120.         }
  121.     [self scrollCellToVisible:bottomRow :0];
  122.     [self scrollCellToVisible:topRow :0];
  123.     [slaves makeObjectsPerform:@selector(scrollDown:) with:self];
  124.     return self;
  125. }
  126.  
  127. - scrollUp:sender
  128. {
  129.     if ((master != nil) && ([sender class] != [BrowserMatrix class]))
  130.         return self;
  131.     if (--topRow < 0) {
  132.         topRow = 0;
  133.         return self;
  134.         }
  135.     [self scrollCellToVisible:topRow :0];
  136.     [slaves makeObjectsPerform:@selector(scrollUp:) with:self];
  137.     return self;
  138. }
  139.  
  140. - addEntry:(const char *)text leaf:(BOOL)yn
  141. {
  142.     int row, count, i, selectable;
  143.     id newCell, cells, slave;
  144.     const char *name;
  145.     
  146.     if (master == nil) {
  147.         if (alphabetize) {
  148.             for (row = 0; row < numRows; row++) {
  149.                 name = [[cellList objectAt:row] stringValue];
  150.                 if (strcmp (name, text) >= 0) break;
  151.                 }
  152.             }
  153.         else row = numRows;
  154.         [self insertRowAt:row];
  155.         slaveRow = row;
  156.         count = [slaves count];
  157.         for (i = 0; i < count; i++) {
  158.             slave = [slaves objectAt:i];
  159.             [slave addEntry:"" leaf:YES];
  160.             }
  161.         selectable = YES;
  162.         }
  163.     else {
  164.         row = slaveRow;
  165.         [self insertRowAt:row];
  166.         selectable = NO;
  167.         }
  168.     newCell = [self cellAt:row :0];
  169.     [newCell setSelectable:selectable];
  170.     [newCell setEditable:NO];
  171.     [newCell setLeaf:yn];
  172.     [newCell setStringValue:text];
  173.     [self selectEntryAt:row];
  174.     return self;
  175. }
  176.  
  177. - removeEntry:aCell
  178. {
  179.     int row, col;
  180.     
  181.     if (master == nil)
  182.         [self getRow:&row andCol:&col ofCell:aCell];
  183.     else row = (int)aCell;
  184.     [self removeRowAt:row andFree:YES];
  185.     [slaves makeObjectsPerform:@selector(removeEntry:) with:(id)row];
  186.     if (master == nil) [self display];
  187.     return self;
  188. }
  189.  
  190. - listFiles:(const char *)dir suffix:(const char *)sfx
  191. {
  192.     char command[128], *fgets(), *pt;
  193.     FILE *pipe, *popen();
  194.     void pclose();
  195.     struct stat statbuf;
  196.     BOOL oldalpha;
  197.     
  198.     oldalpha = alphabetize;
  199.     alphabetize = NO;
  200.     sprintf (command, "/bin/ls -1d 2>/dev/null %s/*", dir);
  201.     if (sfx != NULL) {
  202.         strcat (command, ".");
  203.         strcat (command, sfx);
  204.         }
  205.     pipe = popen (command, "r");
  206.     while (fgets (command, 128, pipe) != NULL) {
  207.         command[strlen (command) - 1] = '\0';
  208.         stat (command, &statbuf);
  209.         if ((pt = rindex (command, '/')) != NULL) pt++;
  210.         else pt = command;
  211.         [self addEntry:pt leaf:!(statbuf.st_mode & S_IFDIR)];
  212.         }
  213.     pclose (pipe);
  214.     alphabetize = oldalpha;
  215.     return self;
  216. }
  217.  
  218. - setMaster:anObject
  219. {
  220.     master = anObject;
  221.     return self;
  222. }
  223.  
  224. - addSlave:aBrowserMatrix
  225. {
  226.     if (master == nil) {
  227.         [slaves addObjectIfAbsent:aBrowserMatrix];
  228.         [aBrowserMatrix setMaster:self];
  229.         }
  230.     return self;
  231. }
  232.  
  233. - setAlphabetize:(BOOL)yn
  234. {
  235.     alphabetize = yn;
  236.     return self;
  237. }
  238.  
  239. - free
  240. {
  241.     [slaves free];
  242.     [super free];
  243.     return self;
  244. }
  245.  
  246. @end
  247.  
  248.